/**
 * @author ahamme
 * @date   2009
 * @update 2010 05 small format changes of JRadioButtonMenuItem
 * @update 2010 06 added progress bar functionality to deleteSelectedIndices(int[])
 * @update 2010 11 delete functionality now simply with keyboard delete button instead of alt+delete
 * @update 2010 11 deletion of virtual images (files) without threads (is now faster)
 * @update 2011 01 19 added IqmOperatorJFrame.updateIqmOperatorGUI() to left click mouse event
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package main;

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.media.jai.PlanarImage;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JButton;
import javax.swing.ScrollPaneConstants;

import opgui.IqmOperatorJFrame;


import java.io.*;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.awt.Dimension;

public class TankFrame extends JFrame implements ActionListener, MouseListener {

    private static final long serialVersionUID = 1L;
    //private static JPanel jContentPane = null;
    //private static JToolBar jJToolBarBar = null;
    public static JRadioButtonMenuItem tankOpt1 = null;
    public static JRadioButtonMenuItem tankOpt2 = null;
    public static JRadioButtonMenuItem tankOpt3 = null;
    public static JRadioButtonMenuItem tankOpt4 = null;
    private static JScrollPane jScrollPane = null;
    private static JButton jButton = null;
    public static JFrame TankFrame = null;  //  @jve:decl-index=0:visual-constraint="10,23"
    public static JList TankList = null;
    public static DefaultListModel model = null; //Model where planar images and description is stored
    //private static ButtonGroup group = null;

    /**
     * This method initializes Tank
     * It groups the Option RadioButtons
     *
     */
    public TankFrame() {
    }

    /**
     * This method creates and shows the GUI
     * @return void
     */
    public void createAndShowGUI() {
        TankFrame = new JFrame();
        TankFrame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);  //TankFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE );
        // Get the size of the default screen
        Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
        int width = dimScreen.width - 4;
        int height = 150;
        int xLoc = 2;
        int yLoc = dimScreen.height - 180;
        //TankFrame.setSize(width, height);
        TankFrame.setLocation(xLoc, yLoc);
        //frame.setLocationRelativeTo( null
        //TankFrame.setIconImage(new ImageIcon("imgs/IqmLogoBlue32.gif").getImage());
        URL url = ClassLoader.getSystemResource("imgs/IqmLogoGreen32_v5.png");
        if (url != null) {
            TankFrame.setIconImage(new ImageIcon(url).getImage());
        }

        TankFrame.setTitle("Tank");
        TankFrame.setContentPane(getJContentPane());
        TankFrame.setResizable(true);
        TankFrame.pack();
        TankFrame.setVisible(true);




    }

    /**
     * This method destroys the GUI
     */
    public void destroyGUI() throws Exception {
//		class MyDestroyable implements Runnable {						
//			@Override
//			public void run() {
        model.removeAllElements();
        //TankList.removeAll(); //zu viel des Guten
        //TankList.repaint();
        TankList = null;
        //model.clear();
        //model = null;
        TankFrame.validate();
        TankFrame.repaint();
        TankFrame.setVisible(false);
        //TankFrame.dispose();
        TankFrame = null;
//			}
//		}
//		ExecutorService exec = Executors.newSingleThreadExecutor();	
//		MyDestroyable MyDest = new MyDestroyable(); 
//		Future<?> future = exec.submit(MyDest);	
//		Object ob = future.get();
//		//if (ob == null) BoardJ.appendTexln("Tank: Manager destroyed successfully");
//		exec.shutdown();
//		boolean b = false;
//		b = exec.awaitTermination(1, TimeUnit.SECONDS);
        IqmTools.setCurrTankIndex(-1);
        //System.out.println("Tank: Tank destroyed: " + b);
        System.out.println("Tank: Tank destroyed: ");
        System.gc();
    }


    
    /**
     * This method initializes jContentPane
     *
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        //if (jContentPane == null) {
        JPanel jContentPane = new JPanel();
        jContentPane.setLayout(new BorderLayout());
        jContentPane.add(getJJToolBarBar(), BorderLayout.WEST);
        jContentPane.add(getJScrollPane(), BorderLayout.CENTER);
        getJRadioButtonMenuItemButtonGroup();
        //}
        return jContentPane;
    }

    /**
     * This method initializes jJToolBarBar
     *
     * @return javax.swing.JToolBar
     */
    private JToolBar getJJToolBarBar() {
        //if (jJToolBarBar == null) {
        JToolBar jJToolBarBar = new JToolBar("Options");
        jJToolBarBar.setOrientation(1); //Vertical orientation
        jJToolBarBar.add(getJRadioButtonMenuItem1());
        jJToolBarBar.add(getJRadioButtonMenuItem2());
        jJToolBarBar.add(getJRadioButtonMenuItem3());
        jJToolBarBar.add(getJRadioButtonMenuItem4());
        jJToolBarBar.addSeparator();
        jJToolBarBar.add(getJButton()).setLocation(10, 0);
        //jJToolBarBar.setPreferredSize(new Dimension(70, 70));
        //}
        return jJToolBarBar;
    }

    /**
     * This method makes a JRadioButtonMenueItem button group
     */
    private ButtonGroup getJRadioButtonMenuItemButtonGroup() {
        ButtonGroup group = new ButtonGroup();
        group.add(tankOpt1);
        group.add(tankOpt2);
        group.add(tankOpt3);
        group.add(tankOpt4);
        return group;
    }

    /**
     * This method initializes tankOpt1
     *
     * @return javax.swing.JRadioButtonMenuItem
     */
    private JRadioButtonMenuItem getJRadioButtonMenuItem1() {
        if (tankOpt1 == null) {
            tankOpt1 = new JRadioButtonMenuItem();
            tankOpt1.setText("All");
            //tankOpt1.setBackground(Color.GRAY);
            tankOpt1.setSelected(true);
            //tankOpt1.setPreferredSize(new Dimension(10,10));
            tankOpt1.setBorder(null);
        }
        return tankOpt1;
    }

    /**
     * This method initializes tankOpt2
     *
     * @return javax.swing.JRadioButtonMenuItem
     */
    private JRadioButtonMenuItem getJRadioButtonMenuItem2() {
        if (tankOpt2 == null) {
            tankOpt2 = new JRadioButtonMenuItem();
            tankOpt2.setText("1");
            //tankOpt2.setBackground(Color.LIGHT_GRAY);
            //tankOpt2.setPreferredSize(new Dimension(10,10));
            tankOpt2.setBorder(null);
        }
        return tankOpt2;
    }

    /**
     * This method initializes tankOpt3
     *
     * @return javax.swing.JRadioButtonMenuItem
     */
    private JRadioButtonMenuItem getJRadioButtonMenuItem3() {
        if (tankOpt3 == null) {
            tankOpt3 = new JRadioButtonMenuItem();
            tankOpt3.setText("10");
            //tankOpt3.setBackground(Color.WHITE);
            //tankOpt3.setPreferredSize(new Dimension(10,10));
            tankOpt3.setBorder(null);
        }
        return tankOpt3;
    }

    /**
     * This method initializes tankOpt4
     *
     * @return javax.swing.JRadioButtonMenuItem
     */
    private JRadioButtonMenuItem getJRadioButtonMenuItem4() {
        if (tankOpt4 == null) {
            tankOpt4 = new JRadioButtonMenuItem();
            tankOpt4.setText("50");
            //tankOpt4.setPreferredSize(new Dimension(10,10));
            tankOpt4.setBorder(null);

        }
        return tankOpt4;
    }

    /**
     * This method initializes jButton
     *
     * @return javax.swing.JButton
     */
    private JButton getJButton() {
        if (jButton == null) {
            jButton = new JButton();
            jButton.setText("Delete");
            jButton.setMnemonic(KeyEvent.VK_DELETE); //keyboard alt + delete 
            jButton.addActionListener(this);
            jButton.setActionCommand("delete");
        }
        return jButton;
    }

    /**
     * This method initializes jScrollPane
     *
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getJScrollPane() {
        if (jScrollPane == null) {
            jScrollPane = new JScrollPane();
            jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
            Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
            int width = dimScreen.width - 90;
            jScrollPane.setPreferredSize(new Dimension(width, 122));
            //jScrollPane.setMinimumSize (new Dimension(400, 100));
            //jScrollPane.setBackground(Color.gray);
            jScrollPane.setViewportView(getJList());
        }
        return jScrollPane;
    }

    /**
     * This method initializes TankList
     *
     * @return javax.swing.JList
     */
    public JList getJList() {
        if (TankList == null) {
            TankList = new JList();
            if (model == null) {
                model = new DefaultListModel();
            }
            TankList.setModel(model);  //nur zum initialisieren
            //ListCellRenderer TankListCellRenderer = null;
            TankList.setCellRenderer(new TankListCellRenderer());  //eigener JLabel Renderer f_r icon und text
            TankList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
            TankList.setVisibleRowCount(1);
            //TankList.addListSelectionListener(null);
            //TankList.setFixedCellWidth(120);
            //TankList.setFixedCellHeight(120);

            TankList.addMouseListener(this);


            TankList.addKeyListener(new java.awt.event.KeyAdapter() {
                @Override
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jListKeyReleased(evt);
            }
        });
        }
        return TankList;
    }


    public void jListKeyReleased(java.awt.event.KeyEvent evt) {
        if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
            int[] indices = TankList.getSelectedIndices();
            this.deleteSelectedIndices(indices);
        }
    }



    /**
     * This method deletes all images in the Tank
     */
    public void deleteAllIndices() {
        int size = model.getSize();
        System.out.println("TankFrame: delete " + size + " items");
        if (size > 0) { //only if there are really items to delete
            int[] indices = new int[size];
            for (int i = 0; i < size; i++) {
                indices[i] = i;
            }
            this.deleteSelectedIndices(indices);
        }
        IqmTools.setCurrTankIndex(-1);
    }

    /**
     * This method deletes images of selected indices
     * @param int[] indices selected indices
     */
    private void deleteSelectedIndices(int[] indices) {
        Manager.setProgressBarStack(0);
        for (int i = indices.length - 1; i >= 0; i--) {
            int proz = (i + 1) * 100;
            proz = 100 - proz / (indices.length);
            Manager.setProgressBarStack(proz);
            deleteSelectedIndex(indices[i]);
        }
        Manager.setProgressBarStack(0);
    }

    /**
     * This method deletes images of the selected index
     * @param int index selected index
     */
    private void deleteSelectedIndex(int index) {
        if (index == -1) {
            System.out.println("TankFrame: no images available to delete");
            return;
        }
        Object ob = ((DefaultListModel) model.getElementAt(index)).firstElement();
        this.deleteSelectedIndexFromTank(index);
        if (ob instanceof PlanarImage) { //reeller  Stack
            //do nothing
        }
        if (ob instanceof File) { //virtueller  Stack
            try {
                this.deleteSelectedIndexFromHD(((File) ob).getParentFile());
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
        IqmTools.setCurrTankIndex(-1);

    }

    /**
     * This method deletes the selected images from the tank
     * @param idx int
     */
    private void deleteSelectedIndexFromTank(int idx) {
        model.remove(idx);
        //model.removeElementAt(idx); //geht genauso
        TankList.setModel(model); //nicht unbedingt n_tig
        TankList.revalidate();    //nicht unbedingt n_tig
        Manager.resetModel();
        Manager.resetModel2();
        Look.reset();
        System.out.println("Tank: Image #" + (idx + 1) + " removed from Tank");
        //}
        IqmTools.setCurrTankIndex(-1);
        System.gc();
    }

//    //deleteSelectedIndexFromHD using threads--------------------------------------------------------------------
//    /**
//     * This method deletes all images stored in a directory
//     * This is mainly for the virtual mode
//     * @param dir File
//     * @throws InterruptedException
//     */
//    private void deleteSelectedIndexFromHD(File dir) throws InterruptedException {
//        class MyDeletable implements Runnable {
//
//            private File dir;
//
//            MyDeletable(File dir) {
//                this.dir = dir;
//            }
//
//            public void run() {
//                boolean success = false;
//                while (!success) {
//                    success = IqmTools.deleteDir(this.dir); //dir.delete();
//                    System.out.println("TankFrame: Destroy virtual image success:  " + success);
//                    if (!success) {
//                        try {
//                            Thread.currentThread().sleep(200);
//                        } catch (InterruptedException e) {
//                            // TODO Auto-generated catch block
//                            e.printStackTrace();
//                        }
//                    }
//                }
//
//            }
//        }
//        ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
//        //System.out.println("TankFrame: I'm here") ;						
//        System.out.println("TankFrame: Deletion of:  " + dir);
//        MyDeletable MyDel = new MyDeletable(dir);
//        exec.schedule(MyDel, 500, TimeUnit.MILLISECONDS);
//        exec.shutdown();
//        boolean b = exec.awaitTermination(5, TimeUnit.SECONDS);
//        System.out.println("TankFrame: " + dir + " destroyed: " + b);
//        if (!b) {
//            Toolkit.getDefaultToolkit().beep();
//            JOptionPane.showMessageDialog(null, "It was not possible to delete all temporary files", "WARNING", JOptionPane.CANCEL_OPTION);
//        }
//        System.gc();
//    }

    //deleteSelectedIndexFromHD without using threads--------------------------------------------------------------------
    /**
     * This method deletes all images stored in a directory
     * This is mainly for the virtual mode
     * @param dir File
     * @throws InterruptedException
     */
    private void deleteSelectedIndexFromHD(File dir) throws InterruptedException {
    	boolean success = false;
    	int n = 0;
    	while ((!success) && (n<10)){
    		success = IqmTools.deleteDir(dir); //dir.delete();
            //System.out.println("TankFrame: Destroy virtual image success:  " + success);
            System.out.println("TankFrame: Attempt #"+n+ " to destroy: " + dir + ": " + success);
            n=n+1;
    	}
        if (!success) {
            Toolkit.getDefaultToolkit().beep();
            JOptionPane.showMessageDialog(null, "It was not possible to delete all temporary files", "WARNING", JOptionPane.CANCEL_OPTION);
        }
        System.gc();
    }
    //-------------------------------------------------------------------------------------------------------------------
    
    public void actionPerformed(ActionEvent e) {
        if ("delete".equals(e.getActionCommand())) {
            int[] indices = TankList.getSelectedIndices();
            this.deleteSelectedIndices(indices);
        }//delete
    }

    //MouseListener mouseListener = new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2)) {  //click and left button
            int index = TankList.locationToIndex(e.getPoint());
            Tank.setManager(index);
            IqmOperatorJFrame currGUI = IqmTools.getCurrIqmOperatorGUI();
            if (currGUI != null){
            	currGUI.updateIqmOperatorGUI();
            }
           
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mousePressed(MouseEvent e) {
//	       try {
//			int index = TankList.locationToIndex(e.getPoint());
//			   //System.out.println("Double clicked on Item " + index);
//			   IqmTools.setCurrTankIndex(index);
//			   Tank.setManager();
//	       } catch (Exception e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//	       }		
    }

    @Override
    public void mouseReleased(MouseEvent e) {
//	    if (e.getButton() == MouseEvent.BUTTON1) {  //left button
//	       int index = TankList.locationToIndex(e.getPoint());
//	       //System.out.println("Double clicked on Item " + index);
//	       IqmTools.setCurrTankIndex(index);
//	       Tank.setManager();	  
//	    }
        if (e.getButton() == MouseEvent.BUTTON3) { //right button
            int index = TankList.locationToIndex(e.getPoint());
            this.deleteSelectedIndex(index);
        }
    }
}
